package com.zhoug.map2;

import com.zhoug.logger2.Logger;

import org.osmdroid.events.DelayedMapListener;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.util.BoundingBox;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;

import java.util.Arrays;
import java.util.List;

import androidx.annotation.NonNull;

/**
 * @Author: zhoug
 * @Date: 2025-01-06
 * @Description:
 */
public class PolygonMaskManager {
    private static final String TAG = ">>>PolygonMaskManager";
    private static final boolean DEBUG = false;

    private PolygonMask mPolygonMask;
    private MapView mMapView;
    /**
     * 限制滚动范围
     */
    private boolean mIsLimitBounds = true;
    /**
     * 边距
     */
    private int boundPadding = 30;
    /**
     * 限制最小缩放级别
     */
    private boolean mIsLimitMinZoom = true;
    private boolean mShouldLimitZoom=false;

    public PolygonMaskManager(MapView mapView) {
        this.mMapView = mapView;
    }

    /**
     * 设置边界
     * @param polygon
     */
    public void set(@NonNull PolygonMask polygon) {
        if (mPolygonMask != null) {
            mMapView.getOverlays().remove(mPolygonMask);
        }
        mPolygonMask = polygon;
        mMapView.getOverlays().add(polygon);
        limitBounds();
        mMapView.postInvalidate();
    }

    /**
     * 清除边界
     */
    public void clear() {
        if (mPolygonMask != null) {
            mPolygonMask.remove();
        }
    }

    /**
     * 缩放地图
     */
    private void limitBounds() {
        //计算边界
        double minLatitude = Double.MAX_VALUE;
        double maxLatitude = Double.MIN_VALUE;
        double minLongitude = Double.MAX_VALUE;
        double maxLongitude = Double.MIN_VALUE;
        List<PolygonMask.PolygonHole> polygonBounds = mPolygonMask.getPolygonBounds();
        if (polygonBounds != null && !polygonBounds.isEmpty()) {
            for (PolygonMask.PolygonHole polygonHole : polygonBounds) {
                List<GeoPoint> actualPoints = polygonHole.getActualPoints();
                if (actualPoints != null && !actualPoints.isEmpty()) {
                    for (GeoPoint geoPoint : actualPoints) {
                        double latitude = geoPoint.getLatitude();
                        double longitude = geoPoint.getLongitude();
                        if (latitude < minLatitude) {
                            minLatitude = latitude;
                        }
                        if (latitude > maxLatitude) {
                            maxLatitude = latitude;
                        }
                        if (longitude < minLongitude) {
                            minLongitude = longitude;
                        }
                        if (longitude > maxLongitude) {
                            maxLongitude = longitude;
                        }
                    }

                }
            }
        }
        if (minLatitude != Double.MAX_VALUE && maxLatitude != Double.MIN_VALUE && minLongitude != Double.MAX_VALUE && maxLongitude != Double.MIN_VALUE) {
            //限制最新缩放
            if (mIsLimitMinZoom) {
                mMapView.setMinZoomLevel(3.0);
                mShouldLimitZoom=true;
                mMapView.addMapListener(mLimitZoomListener);
            }
            //限制移动边界
            if (mIsLimitBounds) {
                mMapView.setScrollableAreaLimitLatitude(maxLatitude, minLatitude, boundPadding);
                mMapView.setScrollableAreaLimitLongitude(minLongitude, maxLongitude, boundPadding);
            }
            //全部点显示在地图上
            BoundingBox boundingBox = BoundingBox.fromGeoPoints(Arrays.asList(new GeoPoint(maxLatitude, minLongitude),
                    new GeoPoint(minLatitude, maxLongitude)));
            mMapView.zoomToBoundingBox(boundingBox, true, boundPadding);
        }

    }

    /**
     * 限制滚动范围
     *
     * @param limitBounds
     */
    public void setLimitBounds(boolean limitBounds) {
        this.mIsLimitBounds = limitBounds;
    }

    /**
     * 限制最新缩放级别
     *
     * @param isLimitMinZoom
     */
    public void setLimitMinZoom(boolean isLimitMinZoom) {
        this.mIsLimitMinZoom = isLimitMinZoom;
    }

    /**
     * 设置边距
     *
     * @param boundPadding
     */
    public void setBoundPadding(int boundPadding) {
        this.boundPadding = boundPadding;
    }

    private final DelayedMapListener mLimitZoomListener = new DelayedMapListener(new MapListener() {
        @Override
        public boolean onScroll(ScrollEvent event) {
            onChange();
            return false;
        }

        @Override
        public boolean onZoom(ZoomEvent event) {
            onChange();
            return false;
        }

        private void onChange(){
            double zoomLevelDouble = mMapView.getZoomLevelDouble();
            if (DEBUG) {
                Logger.d(TAG, "onChange:"+zoomLevelDouble);
            }
            if(mShouldLimitZoom){
                mShouldLimitZoom=false;
                mMapView.setMinZoomLevel(zoomLevelDouble);
            }
            mMapView.removeMapListener(mLimitZoomListener);
        }
    }, 100);


}
